/*
 * SystemCallLayer.h
 *
 *  Created on: 10/07/2009
 *      Author: banouz
 */

#ifndef SYSTEMCALLLAYER_H_
#define SYSTEMCALLLAYER_H_

#include "FileSystem.h"
#include "map"
#include <pthread.h>

#define RO 0     //Read only
#define WO 1     //Write only
#define RW 2     //Read Write
#define CO 3     //Create only

struct fd {
  int offset;
  int permissions;
  int pointer;
  int fdID;
  char* fileName;
  pthread_mutex_t m_WriteLock;
  int lastPermis ;
  int numOfRead ;
  };

class SystemCallLayer
{
private :

  FileSystem* _fileSys;
  map <int,fd*>* _openFDTable;  // fd number,struct fd //TODO make as pointer
  map<int,fd*>* _closeFDTable; //Eran
  int _fdNumbers [128];

  map <int,string>* _i_nodes_table;    // int - i node number , char* file/dir name
  map <string,int>* _revers_i_nodes_table;

  pthread_mutex_t  _mutex_lockB;


public:
  SystemCallLayer();
  virtual
  ~SystemCallLayer();
  /*
   * creates and opens a new file named ‘file_name’ returning a fd to the new file.
   *  If type is soft-link mark it as such. Opens the file with the specified permissions.
   */
  int MakeFile(char* file_name,char type, int flag_access_permissions) ;
  /*
   * creates a hard link with name file-name, linked to target.
   */
  int MakeHLink(char* target_file_name, char* file_name);
 /*
  *  creates a new directory named ‘dir-name’
  */
  int MakeDir(char* dir_name);
  /*
   * removes the directory ‘dir-name’
   */
  int RmDir(char* dir_name) ;
  /*
   * removes the file ‘file-name’
   */
  int RmFile(char* file_name) ;
  /*
   * lists the content of the location-directory. Return list in buf.
   */
  int ls(char* dir_name, char* buf);
  /*
   * opens the file ‘file-name’. Needs to deal with soft-links.
   * Opens the file with the specified permissions.
   */
  int Open(char* filename,char flag_access_permissions);
  /*
   * closes the entry of the file in the file table, and frees the entry in the fd table.
   */
  int Close(int fd) ;
  /*
   *moves the file curser to ‘location’.
   */
  int Seek(int fd, int location) ;
  /*
   * reads nBytes from the received file into the buffer.
   */
  int Read (int fd, int nBytes, char *Buffer) ;
  /*
   *  writes nBytes from buffer into the file.
   */
  int Write (int fd, int nBytes,char * Buffer) ;
  /*
   *moves the file oldName to newName. This function allows moving files to
   *moves  different directories and \ or change the files name.
   */
  int moveFile(char* oldName, char* newName) ;
  /*
   * Ret urns whether this address is a directory or not. Needs to deal with soft-links.
   */
  bool isDir(char * address);
/*
 * - locks file, so that only read operations are allowed.
 * There is no limit on the number of processes that are allowed to
 * concurrently read the file. No processes are allowed to write to the file if there
 *  is an open read lock on the file. It is not obligatory to lock the file to read it.
 *   You should not block if it is locked rather return an error.
 */
  int lockRead (int fd);
/*
 * locks file, so that only one process may hold the lock. This process may write to the file, and no other
 *  files may write to it or read from it. A child does not inherit this
 */
  int lockWrite(int fd) ;
 /*
  *  releases the reading lock held by this process.
  *  Only the process which locked the file may release the lock.
  */
  int releaseLockRead (int fd) ;

  int releaseLockWrite(int fd);

  char* namePading(char* file_name) ;

  void add_to_tables(int i_node,char* ap);

  /**  0 - gets the path , 1 - gets the filename */
  string get_path(char* path,int type);

  /********** print tables *******************/
   void print_tables();

   int get_file_size(char* file_name);

   bool is_exists(char* file_name);

   bool is_fd_open(int fdID);

   int get_fd_by_iNode(int i_node);


   ////////////////Eran//////////

      map<int,fd*> *getOpenFDTable() const
         {
             return _openFDTable;
         }

         void setOpenFDTable(map<int,fd*> *_openFDTable)
         {
             this->_openFDTable = _openFDTable;
         }

         map<int,fd*> *getCloseFDTable() const
         {
             return _closeFDTable;
         }

         void setCloseFDTable(map<int,fd*> *_closeFDTable)
         {
             this->_closeFDTable = _closeFDTable;
         }

         map<string,int> *getRevers_i_nodes_table() const
         {
             return _revers_i_nodes_table;
         }

         void setRevers_i_nodes_table(map<string,int> *_revers_i_nodes_table)
         {
             this->_revers_i_nodes_table = _revers_i_nodes_table;
         }



};

#endif /* SYSTEMCALLLAYER_H_ */
